# -*- coding: UTF-8 -*-
#python3.4.3+ 测试通过   ver1.2
# Python TCP广播服务器
#使用django,sqlite3数据库,支持用户登录注册。 
#功能：将接收到的数据，广播给所有注册的客户。
# 测试：android4.3-发送回显数据_登录_控制多灯_客户端ver1.4 
import sys
import socket
import threading

from django.shortcuts import HttpResponse
from myAPI.getServerIP import getServerIP
from django_sqlite3_API import add, is_name_pass, is_macaddrs, del_macaddrs  #用户登录注册
BUFFER_SIZE = 1024

#下列设置的参数都是android4.3手机有关
TCP_PORT = 8080
TCP_IP = getServerIP()   #例如：192.168.3.142
LOGIN_OK =    "#*LoGoK*#"  #登录成功关键字
REGISTER_OK = "#*ReGoK*#"  #注册成功关键字
FAIL_NO =     "FFFFFFFFF"  #失败关键字

class server():

    def __init__(self):
        self.CLIENTS = []        


    def startServer(self):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.bind((TCP_IP,TCP_PORT))
            s.listen(10)
            #print("Socket服务器 ip地址、端口: ", TCP_IP, TCP_PORT)
            while 1:
                print('%s:%s Socket TCP服务器'%(TCP_IP, TCP_PORT))
                client_socket, addr = s.accept()
                print ("%s:%s"%(addr[0],addr[1]))
                # 注册客户端
                self.CLIENTS.append(client_socket)
                print ("客户数：", len(self.CLIENTS))
                threading.Thread(target=self.recvHandler, args=(client_socket,)).start()
            s.close()
        except socket.error as msg:
            print ('线程错误：%s '%msg) 
            sys.exit()

    def recvHandler(self, client_socket):
        while True:
            data = ''
            try:
                print('%s:%s Socket TCP服务器，等待接收数据...'%(TCP_IP, TCP_PORT))
                data = client_socket.recv(BUFFER_SIZE) #可以接收 浏览器GET、POST来的数据
            except socket.error as msg:
                if isinstance(client_socket, list): 
                    self.CLIENTS.remove(client_socket)
            #如果是浏览器GET来的数据
            if "GET" in str(data):
                data = self.get_data(data)
                print('GET接收数据 data=%s'%(data))
            #如果是浏览器POST来的数据      
            elif "POST" in str(data):
                data = self.post_data(data) 
                print('POST接收数据 data=%s'%(data))   
            if not data: 
                break
            #处理登录、注册、广播...
            strdata = data.decode()
            if "login*#" in strdata: #login处理登录...
                self.broadcast(self.login(strdata))
            elif "regis*#" in strdata: #处理注册...
                self.broadcast(self.register(strdata))
            else: #处理广播...
                self.broadcast(data)

    def broadcast(self, data):
        # 广播
        for client in self.CLIENTS:
            try:
                client.send(data)
                print("广播: ", client, data)
            except socket.error as msg:
                # 取消注册
                self.CLIENTS.remove(client)

        print ("线程中客户数：", len(self.CLIENTS))
       
    def regadd(self, i1, i2, i3):
    	s = FAIL_NO #失败关键字
    	if add(i1, i2, i3): #写入数据库
    		s = REGISTER_OK  #注册成功关键字
    		print("注册成功！", (i1, i2, i3))
    	else:
    		print("注册失败！", (i1, i2, i3))
    	return s.encode()

    def register(self, strdata):
        '''
        手机用户只能注册一次，若忘记密码，重新注册，则删除以前的注册。
        注册成功,返回关键字：REGISTER_OK  、 失败返回：FAIL_NO  
        strdata格式: 用&分割。为了防止出错，若输入字符串（例如：NAME）时输入了"&"，就替换为""
        regis*#&wj&888 

        '''
        s = FAIL_NO #失败关键字
        items = strdata.strip().split('&') #去两边空格后分割
        if is_macaddrs(items[3]):
        	if del_macaddrs(items[3]):
        		return self.regadd(items[1], items[2], items[3])
        	else:
        		print("用户只能注册一次，写入数据库失败！", items[1], find_all())
        		return s.encode()   
        return self.regadd(items[1], items[2], items[3])   

    def login(self, strdata):
        '''
        登录成功,返回关键字：LOGIN_OK 、 失败返回：FAIL_NO 
        strdata格式: 用&分割。为了防止出错，若输入字符串（例如：NAME）时输入了"&"，就替换为""
        login*#&admin&123   login*#&wj&888
        '''
        s = FAIL_NO #失败关键字
        items = strdata.strip().split('&')
        if is_name_pass(items[1], items[2]):
            s = LOGIN_OK  #登录成功,返回关键字
            print("登录成功 NAME=%s PASSWORD=%s"%(items[1], items[2]))
        else:
            print("登录失败 NAME=%s PASSWORD=%s"%(items[1], items[2]))
        return s.encode()

    def get_data(self, data):
        #GET数据格式：GET Aname /hk...
        data = str(data).split(' ')[1]
        data = data[1:].encode("gbk")  #获得name
        #print("EGT: ", data)
        return data   

    def post_data(self, data):
        #POST数据格式：POST ?name=name&password=password b/hk....
        data = str(data).split('?')[1]
        data = data.split(' ')[0]
        items = data.split('&')
        name = items[0].split('=')[1]
        password = items[1].split('=')[1]
        data = "%s&%s"%(name, password)
        data = data.encode("gbk") #获得name&password
        #print("POST: ", data)    
        return data    
        

        

if __name__ == '__main__':
    s = server() #创建新服务器侦听连接
    threading.Thread(target=s.startServer).start()
